"Green-bar" paper on a LaserJet II ---------------------------------- This document explains how to shade every other line of a LaserJet II-printed report so that the result is similar to that produced on "green bar" paper stock. This makes it easier to read reports such as data file listings, etc., where each line is a record. Printer functions required -------------------------- The technique involves two basic LJ functions: cursor positioning and rectangular area filling. These are documented in the "LaserJet Series II Printer Technical Reference Manual", available at extra cost from Hewlett-Packard (Part No. 33440-90905). The area filling functions allow you to define a rectangular box and fill it with the pattern or shading level of your choice. We will use a box that is 8.5" wide and 1/6" high--the full width of the paper by one line high. It is then "filled" by shading. The cursor positioning functions move the "cursor", which is the active printing location--where the next character will print. It is analagous to a screen cursor. In essence, we will start at the upper left corner of the page and shade every other line by moving the cursor down two lines after each fill. Algorithm --------- The basic algorithm is: Save the "cursor" position Move the cursor to the upper left corner of the page Define the box characteristics Do 30 times Shade the box Move the cursor down two lines End do Restore the initial cursor position At the end of this process, every other line has been shaded. The character data is then sent to the printer as usual for printing. Specific functions used ----------------------- "Ec" is an ASCII ESC character (decimal code 27, hex 1B). "#" is a variable value that is replaced by a numeric parameter (in ASCII: for example, "50" is transmitted by sending the ASCII characters "5" and "0"). Note: the LJ-II commands show below have been simplified somewhat, i.e., the definitions shown don't necessarily convey all possible formats of the commands given. 1. Cursor positioning a. Save/restore cursor position Ec&f0S This saves the current cursor position by pushing it onto a LIFO stack. It can be restored (popped) by the control string Ec&f1S The stack is large enough to save 20 cursor positions. b. Set cursor position (horizontal absolute, by dots) Ec*p#X The variable value # is the horizontal dot number. The leftmost dot on a row is dot 0, so the control string Ec*p0X moves the cursor to the left side of the page. c. Set cursor position (vertical absolute, by dots) Ec*p#Y The variable value # is the vertical dot number. The topmost dot row on the page is row 0. To put the cursor at the top of the page: Ec*p0Y d. Set cursor position (vertical relative, by rows) Ec&a#R The variable value is preceded by a plus or minus sign to indicate whether the cursor is to be moved up (-) or down (+) the specified number of rows. This moves the cursor down two rows: Ec&a+2R 2. Area filling a. Define box width (in dots) Ec*c#A To define a box 8.5" wide (8.5 x 300 = 2550 dots): Ec*c2550A Note that the printer will clip the box at the left and right margins. b. Define box height (in dots) Ec*c#B To define a box 1/6" (one line) high: Ec*c50B 1/6" at 300 dots per inch is 50 dots. c. Define shading level Ec*c#G The variable value # represents a shading level from 2% to 100%. The printer can actually print eight different levels, and there are some discrepancies in the HP manual regarding these levels. However, 2, 10, 15, 30, 45, 70, 90, and 100% would seem to represent the real levels. To set 15% shading: Ec*c15G I suggest 10% or 15% shading for the "green bar" paper. d. Print box as currently defined Ec*c2P This control string performs the gray scale fill using the area dimensions and fill level currently defined. The box is printed at the current cursor position; the cursor position is not changed. As always, no physical printing occurs until the page is filled with text data or a formfeed is received. Combining functions ------------------- The LJ-II allows some concatenation of control strings. Strings may be concatenated if the first two characters following the ESC are the same: Ec*p#X Ec*p#Y If strings are combined, the trailing character for all control strings except the last one is lowercase, and the first three characters are omitted after the first string. For example, the three strings Ec*c2550A Ec*c50B Ec*c15G can be combined into one string as follows: Ec*c2550a50b15G Margins etc. ------------ This document assumes that you're using 8.5 x 11 paper at 60 lines per page (i.e., with the default top and bottom margins), six lines per inch, in portrait mode. If you use anything else, you'll need to adjust some of the parameters. The left/right margins have no effect on the printing of the shaded rectangles, but the top margin and text length do. In other words, dot column 0 is an absolute position on the page, but dot row 0 is relative to the top margin. If you print shaded boxes beyond the bottom of the text area, a page eject will occur (and you'll have a shaded page with no text). Sample code ----------- Each of the following code samples sends the following control sequences to the printer: Ec&f0S ; Save curpos Ec*p0x0Y ; Cursor to (0,0) Ec*c2550a50b10G ; Define box: 8.5" x 1/6", 10% shading (30 times:) Ec*c2P ; Print box Ec&a+2R ; Move down two lines Ec&f1S ; Restore curpos Some of these have been combined for greater efficiency. This code must be executed for each page printed, of course. If you are going to be printing many pages, it may be faster (especially in dBASE!) to contatenate 30 instances of Ec*c2PEc&a+2R into one string (and print it once per page) than to send the string to the printer thirty times for each page. BASIC: 100 EC$ = CHR$(27) 110 LPRINT EC$ + "&f0S" + EC$ + "*p0x0Y" + EC$ + "*c2550a50b10G"; 120 FOR I = 1 TO 30: LPRINT EC$ + "*c2P" + EC$ + "&a+2R";: NEXT 130 LPRINT EC$ + "&f1S"; C: int i; fprintf (stdprn, "\033&f0S\033*p0x0Y\033*c2550a50b10G"); for (i=1; i <= 30; i++) fprintf (stdprn, "\033*c2P\033&a+2R"); fprintf (stdprn, "\033&f1S"); dBASE III+: set print on set console off Ec = chr(27) ?? Ec + "&f0S" + Ec + "*p0x0Y" + Ec + "*c2550a50b10G" i = 1 do while i <= 30 ?? Ec + "*c2P" + Ec + "&a+2R" i = i+1 enddo ?? Ec + "&f1S" set print off set console on dBASE IV: ??? "{ESC}&f0S{ESC}*p0x0Y{ESC}*c2550a50b10G" i = 1 do while i <= 30 ??? "{ESC}*c2P{ESC}&a+2R" i = i+1 enddo ??? "{ESC}&f1S" REXX: Ec = '1B'x call charout 'prn',Ec'&f0S'Ec'*p0x0Y'Ec'*c2550a50b10G' do 30 call charout 'prn',Ec'*c2P'Ec'&a+2R' end call charout 'prn',Ec'&f1S' =============================================== Document by: Chris Dunford The Cove Software Group PO Box 1072 Columbia, MD 21044 301/992-9371 CompuServe 76703,2002 Prepared for: CompuServe IBMNET 02/01/89